<template>
  <div class="range-date-picker">
    <div class="groups"></div>
    <div class="date-filter">
      <el-radio-group
        v-if="ranges?.length > 1"
        v-model="dateRangeType"
        class="range-type"
        size="mini"
        @change="onRangTypeChange">
        <el-radio-button v-if="ranges.includes('month')" label="month">按月</el-radio-button>
        <el-radio-button v-if="ranges.includes('quarter')" label="quarter">按季</el-radio-button>
        <el-radio-button v-if="ranges.includes('year')" label="year">按年</el-radio-button>
      </el-radio-group>
      <div class="date-picker">
        <el-popover v-model="popoverVisible" popper-class="filter-date-popper" placement="bottom-start" trigger="click">
          <div class="date-value-view" slot="reference">
            <i class="el-icon-date"></i>
            <div class="value-display">
              <span class="date-item">{{ startDateDisplay }}</span>
              <span class="date-spliter">至</span>
              <span class="date-item">{{ endDateDisplay }}</span>
            </div>
            <i v-if="startDate.value" class="el-icon-circle-close" @click="clearRangeValue"></i>
          </div>
          <div class="picker-popover">
            <div class="shortcut">
              <div v-for="item in shortcuts[dateRangeType]" :key="item.value" @click="onShortCutClick(item.value)">
                {{ item.label }}
              </div>
            </div>
            <div class="date-content" :class="dateRangeType">
              <div class="picker-item picker-left">
                <div class="date-header">
                  <div class="pre-btn" @click="onLeftPre">
                    <i class="el-icon-arrow-left"></i>
                  </div>
                  <div class="current">{{ leftRangeDisplay }}</div>
                  <div class="next-btn" :class="{ disable: pageBtnDisable }" @click="onLeftNext">
                    <i class="el-icon-arrow-right"></i>
                  </div>
                </div>
                <div class="date-table">
                  <div
                    v-for="item in dateTableLeft"
                    class="date-cell"
                    :class="getItemClass(item)"
                    :key="item.value"
                    @click="onDateCellClick(item)"
                    @mouseenter="onCellDataMouseEnter(item)">
                    <span>
                      {{ item.label }}
                    </span>
                  </div>
                </div>
              </div>
              <div class="picker-item picker-right">
                <div class="date-header">
                  <div class="pre-btn" :class="{ disable: pageBtnDisable }" @click="onRightPre">
                    <i class="el-icon-arrow-left"></i>
                  </div>
                  <div class="current">{{ rightRangeDisplay }}</div>
                  <div class="next-btn" @click="onRightNext">
                    <i class="el-icon-arrow-right"></i>
                  </div>
                </div>
                <div class="date-table">
                  <div
                    v-for="item in dateTableRight"
                    class="date-cell"
                    :class="getItemClass(item)"
                    :key="item.value"
                    @click="onDateCellClick(item)"
                    @mouseenter="onCellDataMouseEnter(item)">
                    <span>
                      {{ item.label }}
                    </span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </el-popover>
      </div>
    </div>
  </div>
</template>

<script>
import { padLeftZero, getMonthEndDate } from '@utility/utility'
export default {
  name: 'RangeDatePicker',
  model: {
    prop: 'val',
    event: 'change',
  },
  props: {
    val: {
      type: Object,
      default: () => ({ type: 'month', startDate: '', endDate: '' }),
    },
    ranges: {
      type: Array,
      default: () => ['month', 'quarter', 'year'],
    },
    autoInit: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      popoverVisible: false,
      dateRangeType: '', // month, quarter, year
      shortcuts: {
        month: [
          {
            value: 'curr-year',
            label: '今年',
          },
          {
            value: 'last-year',
            label: '去年',
          },
          {
            value: 'past-year',
            label: '最近1年',
          },
        ],
        quarter: [
          {
            value: 'curr-year',
            label: '今年',
          },
          {
            value: 'last-year',
            label: '去年',
          },
          {
            value: 'last-past-year',
            label: '去年至今',
          },
        ],
        year: [
          {
            value: 'past-3-years',
            label: '最近3年',
          },
          {
            value: 'past-5-years',
            label: '最近5年',
          },
          {
            value: 'past-10-years',
            label: '最近10年',
          },
        ],
      },
      monthTable: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].map(item => ({
        label: item + ' 月',
        value: item,
      })),
      quarterTable: [1, 4, 7, 10].map((item, idx) => ({
        label: idx + 1 + ' 季度',
        value: idx + 1,
        startMonth: item,
        endMonth: item + 2,
      })),
      startDate: {
        year: '', // 年份
        value: '', // 类型值（年、月、季度类型的具体值）
      },
      endDate: {
        year: '',
        value: '',
      },
      startDateSelecting: null,
      endDateSelecting: null,
      hoverDate: null,
      leftYear: null,
      leftYears: [],
      rightYear: null,
      rightYears: [],
    }
  },
  computed: {
    // 年度列表
    /**
     * {
     *    label 用于展示
     *    year 年份
     *    value 类型值（年、月、季度）
     *    dateValue 预格式化值（补齐0），用于对比
     * }
     */
    dateTableLeft() {
      if (this.dateRangeType === 'month') {
        return this.monthTable.map(item => {
          return { ...item, year: this.leftYear, dateValue: `${this.leftYear}-${padLeftZero(item.value)}` }
        })
      } else if (this.dateRangeType === 'quarter') {
        return this.quarterTable.map(item => {
          return { ...item, year: this.leftYear, dateValue: `${this.leftYear}-${padLeftZero(item.value)}` }
        })
      } else if (this.dateRangeType === 'year') {
        return this.leftYears.map(item => ({ label: item + ' 年', value: item, year: item, dateValue: item + '' }))
      }
      return []
    },
    dateTableRight() {
      if (this.dateRangeType === 'month') {
        return this.monthTable.map(item => {
          return { ...item, year: this.rightYear, dateValue: `${this.rightYear}-${padLeftZero(item.value)}` }
        })
      } else if (this.dateRangeType === 'quarter') {
        return this.quarterTable.map(item => {
          return { ...item, year: this.rightYear, dateValue: `${this.rightYear}-${padLeftZero(item.value)}` }
        })
      } else if (this.dateRangeType === 'year') {
        return this.rightYears.map(item => ({ label: item + ' 年', value: item, year: item, dateValue: item + '' }))
      }
      return []
    },
    leftRangeDisplay() {
      if (this.dateRangeType === 'year') {
        return this.leftYears[0] + ' 年 - ' + this.leftYears[9] + ' 年'
      } else {
        return this.leftYear + ' 年'
      }
    },
    rightRangeDisplay() {
      if (this.dateRangeType === 'year') {
        return this.rightYears[0] + ' 年 - ' + this.rightYears[9] + ' 年'
      } else {
        return this.rightYear + ' 年'
      }
    },
    pageBtnDisable() {
      if (this.dateRangeType === 'year') {
        return this.rightYears[0] - this.leftYears[0] === 10
      }
      return this.rightYear - this.leftYear === 1
    },
    startDateDisplay() {
      if (this.startDate.value) {
        if (this.dateRangeType === 'month') {
          return this.startDate.year + ' 年 ' + this.startDate.value + ' 月'
        } else if (this.dateRangeType === 'quarter') {
          return this.startDate.year + ' 年 ' + this.startDate.value + ' 季度'
        } else {
          return this.startDate.year + ' 年'
        }
      }
      return ''
    },
    endDateDisplay() {
      if (this.endDate.value) {
        if (this.dateRangeType === 'month') {
          return this.endDate.year + ' 年 ' + this.endDate.value + ' 月'
        } else if (this.dateRangeType === 'quarter') {
          return this.endDate.year + ' 年 ' + this.endDate.value + ' 季度'
        } else {
          return this.endDate.year + ' 年'
        }
      }
      return ''
    },
  },
  watch: {},
  mounted() {
    // init by props
    if (this.val && ['month', 'quarter', 'year'].includes(this.val.type)) {
      this.dateRangeType = this.val.type
    } else {
      this.dateRangeType = this.ranges[0] || 'month'
    }

    if (this.val && this.val.startDate && this.val.endDate) {
      const startDate = new Date(String(this.val.startDate))
      const endDate = new Date(String(this.val.endDate))
      this.leftYear = startDate.getFullYear()
      this.rightYear = endDate.getFullYear()

      this.rightYears = this.getLastTenYears(this.leftYear)
      this.leftYears = this.getLastTenYears(this.leftYear - 10)
      this.startDate.value = this.val.startDate
      this.endDate.value = this.val.endDate
      this.startDate.year = this.leftYear
      this.endDate.year = this.rightYear
    } else {
      // 初始化 leftYear rightYear leftYears rightYears
      const yearNow = new Date().getFullYear()
      this.rightYear = yearNow
      this.leftYear = yearNow - 1
      this.rightYears = this.getLastTenYears(yearNow)
      this.leftYears = this.getLastTenYears(yearNow - 10)
      this.setRangeDate()
      if (this.autoInit) {
        this.emitDateChange()
      } else {
        this.startDate = {
          year: '', // 年份
          value: '', // 类型值（年、月、季度）
        }
        this.endDate = {
          year: '',
          value: '',
        }
      }
    }
  },
  methods: {
    onRangTypeChange() {
      this.clearRangeValue()

      this.startDateSelecting = null
      this.endDateSelecting = null
      // this.buildDefaultDate()
      this.setRangeDate()
      this.emitDateChange()
    },
    // 根据时间范围，构建时间区间值
    setRangeDate(startDate, endDate) {
      if (!endDate) {
        endDate = new Date()
      }

      if (startDate > endDate) {
        ;[startDate, endDate] = [endDate, startDate]
      }
      const endYear = endDate.getFullYear()
      const endMonth = endDate.getMonth() + 1

      let startYear
      let startMonth
      if (startDate) {
        startYear = startDate.getFullYear()
        startMonth = startDate.getMonth() + 1
      } else {
        // 设置默认值
        if (this.dateRangeType === 'month') {
          startYear = endYear
          startMonth = 1
        } else if (this.dateRangeType === 'quarter') {
          startYear = endYear
          startMonth = 1
        } else if (this.dateRangeType === 'year') {
          startYear = endYear - 2
          startMonth = 1
        }
      }
      // 按 year month 构建value值
      let startValue = ''
      let endValue = ''

      if (this.dateRangeType === 'month') {
        startValue = startMonth
        endValue = endMonth
      } else if (this.dateRangeType === 'quarter') {
        const startQuarter = Math.ceil(startMonth / 3)
        const endQuarter = Math.ceil(endMonth / 3)

        startValue = startQuarter
        endValue = endQuarter
      } else if (this.dateRangeType === 'year') {
        startValue = startYear
        endValue = endYear
      }

      this.startDate.year = startYear
      this.startDate.value = startValue

      this.endDate.year = endYear
      this.endDate.value = endValue
    },
    emitDateChange() {
      let startValue
      let endValue
      if (this.dateRangeType === 'month') {
        startValue = this.startDate.year + '-' + padLeftZero(this.startDate.value)
        endValue = this.endDate.year + '-' + padLeftZero(this.endDate.value)
      } else if (this.dateRangeType === 'quarter') {
        startValue = this.startDate.year + '-' + padLeftZero((this.startDate.value - 1) * 3 + 1)
        endValue = this.endDate.year + '-' + padLeftZero(this.endDate.value * 3)
      } else {
        startValue = this.startDate.value + '-01'
        endValue = this.endDate.value + '-12'
      }
      // convert year-month to yyy-MM-dd
      startValue += '-01'
      endValue = getMonthEndDate(endValue + '-01')
      this.$emit('change', { type: this.dateRangeType, startDate: startValue, endDate: endValue })
      this.val.type = this.dateRangeType // eslint-disable-line
      this.val.startDate = startValue // eslint-disable-line
      this.val.endDate = endValue // eslint-disable-line
    },
    getLastTenYears(year) {
      // 年取整10
      const startYear = year.toString().substring(0, 3) + '9'
      const years = []
      for (let i = 0; i < 10; i++) {
        years.push(startYear - i)
      }
      return years.reverse()
    },
    onLeftPre() {
      if (this.dateRangeType === 'year') {
        this.leftYears = this.getLastTenYears(this.leftYears[0] - 1)
      } else {
        this.leftYear--
      }
    },
    onLeftNext() {
      if (this.pageBtnDisable) {
        return
      }
      if (this.dateRangeType === 'year') {
        this.leftYears = this.getLastTenYears(this.leftYears[0] + 10)
      } else {
        this.leftYear++
      }
    },
    onRightPre() {
      if (this.pageBtnDisable) {
        return
      }
      if (this.dateRangeType === 'year') {
        this.rightYears = this.getLastTenYears(this.rightYears[0] - 1)
      } else {
        this.rightYear--
      }
    },
    onRightNext() {
      if (this.dateRangeType === 'year') {
        this.rightYears = this.getLastTenYears(this.rightYears[0] + 10)
      } else {
        this.rightYear++
      }
    },
    onDateCellClick(item) {
      if (!this.startDateSelecting || this.endDateSelecting) {
        this.endDateSelecting = null
        this.startDateSelecting = item
        this.hoverDate = item
      } else if (!this.endDateSelecting) {
        this.endDateSelecting = item
        this.hoverDate = null
        // 判断 startDate 和 endDate 的大小
        if (this.startDateSelecting.dateValue < this.endDateSelecting.dateValue) {
          this.startDate.year = this.startDateSelecting.year
          this.startDate.value = this.startDateSelecting.value
          this.endDate.year = this.endDateSelecting.year
          this.endDate.value = this.endDateSelecting.value
        } else {
          this.startDate.year = this.endDateSelecting.year
          this.startDate.value = this.endDateSelecting.value
          this.endDate.year = this.startDateSelecting.year
          this.endDate.value = this.startDateSelecting.value
        }
        this.emitDateChange()
        this.startDateSelecting = null
        this.endDateSelecting = null
        this.popoverVisible = false
      }
    },
    onCellDataMouseEnter(item) {
      if (this.startDateSelecting && !this.endDateSelecting) {
        this.hoverDate = item
      }
    },
    getItemClass(item) {
      const itemDateValue = item.dateValue
      if (this.startDateSelecting) {
        // 选择中
        let startDate = this.startDateSelecting
        let endDate = this.hoverDate || this.endDateSelecting

        const isReverse = endDate.dateValue < startDate.dateValue
        if (isReverse) {
          startDate = endDate
          endDate = this.startDateSelecting
        }
        return _getClass(startDate.dateValue, endDate.dateValue)
      } else if (this.startDate && this.endDate) {
        // 已选择  startDate <= endDate
        const startValue =
          this.startDate.year + (this.dateRangeType !== 'year' ? '-' + padLeftZero(this.startDate.value) : '')
        const endValue =
          this.endDate.year + (this.dateRangeType !== 'year' ? '-' + padLeftZero(this.endDate.value) : '')

        return _getClass(startValue, endValue)
      }
      function _getClass(_startValue, _endValue) {
        if (itemDateValue === _startValue && itemDateValue === _endValue) {
          return 'start-date end-date'
        } else if (itemDateValue === _startValue) {
          return 'start-date'
        } else if (itemDateValue === _endValue) {
          return 'end-date'
        } else if (itemDateValue > _startValue && itemDateValue < _endValue) {
          return 'in-range'
        }
      }

      return null
    },
    clearRangeValue() {
      this.startDate.value = ''
      this.startDate.year = ''

      this.endDate.value = ''
      this.endDate.year = ''
      this.$emit('change', { type: this.dateRangeType, startDate: '', endDate: '' })
    },
    onShortCutClick(val) {
      const startDate = new Date()
      const endDate = new Date()
      if (val === 'curr-year') {
        startDate.setMonth(0, 1)
      } else if (val === 'last-year') {
        startDate.setFullYear(startDate.getFullYear() - 1)
        startDate.setMonth(0, 1)
        endDate.setFullYear(endDate.getFullYear() - 1)
        endDate.setMonth(11, 31)
      } else if (val === 'past-year') {
        startDate.setFullYear(startDate.getFullYear() - 1)
        startDate.setMonth(startDate.getMonth() + 1, 1)
      } else if (val === 'last-past-year') {
        startDate.setFullYear(startDate.getFullYear() - 1)
        startDate.setMonth(0, 1)
      } else if (val === 'past-3-years') {
        startDate.setFullYear(startDate.getFullYear() - 2)
        startDate.setMonth(0, 1)
      } else if (val === 'past-5-years') {
        startDate.setFullYear(startDate.getFullYear() - 4)
        startDate.setMonth(0, 1)
      } else if (val === 'past-10-years') {
        startDate.setFullYear(startDate.getFullYear() - 9)
        startDate.setMonth(0, 1)
      }
      this.setRangeDate(startDate, endDate)
      this.emitDateChange()
      setTimeout(() => {
        this.popoverVisible = false
      }, 500)
    },
  },
}
</script>

<style lang="scss" scoped>
.range-date-picker {
  display: flex;
  align-items: center;
  // padding: 14px 20px;
  .range-type {
    margin-right: 20px;
  }
  .date-picker {
    display: inline-block;
    border: 1px solid #dcdfe6;
    padding: 8px 10px;
    width: 300px;
    vertical-align: middle;
    &:hover {
      border-color: #c0c4cc;
    }
    .date-value-view {
      display: flex;
      .value-display {
        flex: 1;
        font-size: 14px;
        line-height: 14px;
        display: flex;
        align-items: center;
        .date-item {
          text-align: center;
          flex: 1;
        }
        .date-spliter {
          margin: 0 10px;
        }
      }
      i {
        color: #c0c4cc;
      }
      .el-icon-circle-close {
        cursor: pointer;
        &:hover {
          color: #2c63b0;
        }
      }
    }
  }
}
</style>
<style lang="scss">
.filter-date-popper {
  transform: translateY(5px) translateX(-12px);
  padding: 0;
  .picker-popover {
    display: flex;
    .shortcut {
      border-right: 1px solid #e4e4e4;
      padding: 10px;
      line-height: 28px;
      div {
        cursor: pointer;
        &:hover {
          color: #2c63b0;
        }
      }
    }
    .date-content {
      // width: 200px;
      display: flex;
      &.month {
        .picker-item {
          width: 240px;
        }
        .date-cell {
          width: 25%;
        }
      }
      &.quarter {
        .picker-item {
          width: 180px;
        }
        .date-cell {
          width: 50%;
        }
      }
      &.year {
        .picker-item {
          width: 260px;
        }
        .date-cell {
          width: 33.3%;
        }
      }
      .picker-item {
        display: inline-block;
        padding: 10px;
        &:first-child {
          border-right: 1px solid #e4e4e4;
        }

        .date-header {
          display: flex;
          align-items: center;
          border-bottom: 1px solid #ebeef5;
          .pre-btn,
          .next-btn {
            padding: 10px;
            cursor: pointer;
            color: #333;
            &:hover {
              color: #2c63b0;
            }
            &.disable {
              cursor: not-allowed;
            }
          }
          .current {
            flex: 1;
            font-size: 16px;
            text-align: center;
          }
        }
      }
      .date-table {
        display: flex;
        flex-wrap: wrap;
        margin-top: 5px;
        .date-cell {
          padding: 10px 0;
          text-align: center;
          cursor: pointer;
          // background: #f5f5f5;
          user-select: none;
          span {
            // background: #c6e5f1;
            padding: 5px;
            width: 100%;
            display: inline-block;
          }

          &:hover {
            color: #2c63b0;
            // background: #f5f5f5;
          }
          &.in-range {
            span {
              background: #f2f6fc;
            }
          }
          &.start-date {
            span {
              background: #2c63b0;
              color: #fff !important;
              border-top-left-radius: 16px;
              border-bottom-left-radius: 16px;
            }
          }
          &.end-date {
            span {
              background: #2c63b0;
              color: #fff !important;
              border-top-right-radius: 16px;
              border-bottom-right-radius: 16px;
            }
          }
        }
      }
    }
  }
}
</style>
